#include "Session.h"
#include "Server.h"
#include "../mgr/SessionMgr.h"

namespace echo_service
{
	Service::Service() :_tcp(new CTcpIoServer(true)),_svrSock(_tcp.get()->GetTcpServicePtr())
	{
		cout << "Service contract:" << endl;
	}

	Service::~Service()
	{
		cout << "service delete:" << endl;
	}

	void Service::Start(const char* addr, DWORD port)
	{
		auto ec = _svrSock.Socket();
		CHECKERROR(ec, "init sock failed!");
		ec = LibTools::Bind(_svrSock, addr, port);
		CHECKERROR(ec, "bind failed!");
		ec = LibTools::Listen(_svrSock);
		CHECKERROR(ec, "Listen failed!");
		ec = _tcp->Init(_svrSock, true);
		CHECKERROR(ec, "init failed!");
		cout << "listen:" << *_svrSock.GetSockPtr() << ", addr:" << addr << ", port = " << port << endl;
		StartAccept(_tcp.get(), _svrSock);
	}

	void Service::StartAccept(CTcpIoServer* s, CTcpIoSocket& svrSock)
	{
		auto session = new Session(s);
		s->AsyncAccept(svrSock, session->_sock, &Service::HandleAccept, session);
	}

	DWORD Service::HandleAccept(CSockError ec, void* invoker)
	{
		//static int iCount = 1;
		shared_ptr<Session> session((Session*)invoker);
		CTcpIoServer* s = session->GetTcpServer();

		if(!ec)
		{
			mgr::SessionMgr<Session>::Insert(session);
			ec = s->Init(session->_sock);
			session->Start();
			StartAccept(s, *(session->_svrSock));
		}
		else
		{
			LOG_TOOLS(LOG_ERROR) << "accept error=>" << ec.GetErrorMsg();
			//cout << "notify server stop..." << endl;
			//session->GetTcpServer()->NotifyStop();
		}

		return ec;
	}
}